package cn.tqfeiyang.smartadmin.business.organization.service;

import cn.tqfeiyang.smartadmin.business.organization.entity.DepartmentEntity;
import cn.tqfeiyang.smartadmin.business.organization.mapper.DepartmentMapper;
import cn.tqfeiyang.smartadmin.business.organization.request.DepartmentCreateDTO;
import cn.tqfeiyang.smartadmin.business.organization.request.DepartmentUpdateDTO;
import cn.tqfeiyang.smartadmin.business.organization.request.DepartmentQueryDTO;
import cn.tqfeiyang.smartadmin.business.organization.response.DepartmentQueryVO;
import cn.tqfeiyang.smartadmin.business.organization.response.DepartmentDetailVO;

import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import jakarta.annotation.Resource;

import cn.tqfeiyang.smartadmin.commons.exception.BusinessException;
import cn.tqfeiyang.smartadmin.commons.toolbox.BeanUtils;
import cn.tqfeiyang.smartadmin.commons.pagination.PageData;
import cn.tqfeiyang.smartadmin.commons.mybatis.EntityBroadcast;
import cn.tqfeiyang.smartadmin.commons.toolbox.ValidationUtils;

import java.util.List;
import java.util.Objects;

/**
 * 部门CRUD服务
 *
 * @author tqfeiyang
 * @since 2024-10-18
 */
@Service
public class DepartmentCurdService {

    /**
     * 实体广播对象
     */
    @Resource
    private EntityBroadcast entityBroadcast;

    /**
     * 部门映射接口
     */
    @Resource
    private DepartmentMapper departmentMapper;

    /**
     * 分页查询部门
     *
     * @param dto 请求数据
     * @return 部门分页
     */
    public PageData<DepartmentQueryVO> queryDepartments(DepartmentQueryDTO dto) {
        Assert.notNull(dto, "dto不能为空");
        ValidationUtils.validateProperties(dto);

        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        return PageData.create(departmentMapper.queryDepartments(dto));
    }

    /**
     * 查询部门详情
     *
     * @param departmentId 部门id
     * @return 部门详情
     */
    public DepartmentDetailVO readDepartment(Long departmentId) {
        Assert.notNull(departmentId, "departmentId不能为空");
        return departmentMapper.readDepartment(departmentId);
    }

    /**
     * 添加部门
     *
     * @param dto 请求数据
     * @return 部门id
     */
    @Transactional(rollbackFor = Exception.class)
    public Long createDepartment(DepartmentCreateDTO dto) {
        Assert.notNull(dto, "dto不能为空");
        ValidationUtils.validateProperties(dto);

        DepartmentEntity entity = BeanUtils.copy(dto, DepartmentEntity.class);
        entityBroadcast.validate(entity, true);

        departmentMapper.insert(entity);
        entityBroadcast.clearCache(DepartmentEntity.class);
        return entity.getDepartmentId();
    }

    /**
     * 修改部门
     *
     * @param departmentId 部门id
     * @param dto 请求数据
     * @return 部门id
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateDepartment(Long departmentId, DepartmentUpdateDTO dto) {
        Assert.notNull(departmentId, "departmentId不能为空");
        Assert.notNull(dto, "dto不能为空");
        ValidationUtils.validateProperties(dto);

        DepartmentEntity entity = departmentMapper.selectById(departmentId);
        if (Objects.isNull(entity)) {
            throw new BusinessException("部门id不存在({})", departmentId);
        }

        entity = BeanUtils.copy(dto, DepartmentEntity.class);
        entity.setDepartmentId(departmentId);
        entityBroadcast.validate(entity, false);

        departmentMapper.updateById(entity);
        entityBroadcast.clearCache(DepartmentEntity.class);
    }

    /**
     * 删除部门
     *
     * @param departmentId 部门id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteDepartment(Long departmentId) {
        Assert.notNull(departmentId, "departmentId不能为空");

        DepartmentEntity entity = departmentMapper.selectById(departmentId);
        if (Objects.isNull(entity)) {
            throw new BusinessException("部门id不存在({})", departmentId);
        }

        entityBroadcast.beforeDelete(entity);
        departmentMapper.deleteDepartment(departmentId);
        entityBroadcast.afterDelete(entity);
        entityBroadcast.clearCache(DepartmentEntity.class);
    }

    /**
     * 批量删除部门
     *
     * @param departmentIds 部门id列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteDepartments(List<Long> departmentIds) {
        Assert.notNull(departmentIds, "departmentIds不能为空");
        departmentIds.forEach(departmentId -> {
            DepartmentEntity entity = departmentMapper.selectById(departmentId);
            if (Objects.isNull(entity)) {
                throw new BusinessException("部门id不存在({})", departmentId);
            }

            entityBroadcast.beforeDelete(entity);
            departmentMapper.deleteDepartment(departmentId);
            entityBroadcast.afterDelete(entity);
        });
        entityBroadcast.clearCache(DepartmentEntity.class);
    }
}
